// META: title=test WebNN API element-wise identity operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long

'use strict';

// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-unary
// Copy the value of the input tensor to the output tensor, element-wise.
//
// MLOperand identity(MLOperand input);


const getIdentityPrecisionTolerance = (graphResources) => {
  const toleranceValueDict = {float32: 0, float16: 0};
  const expectedDataType =
      getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
  return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
};

const identityTests = [
  {
    'name': 'identity float32 0D scalar',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [-4.273642539978027],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [-4.273642539978027],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 1D constant tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 1D tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 2D tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 3D tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 4D tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'identity float32 5D tensor',
    'graph': {
      'inputs': {
        'identityInput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'identity',
        'arguments': [{'input': 'identityInput'}],
        'outputs': 'identityOutput'
      }],
      'expectedOutputs': {
        'identityOutput': {
          'data': [
            0.377551406621933,   -0.8890897631645203, 9.965806007385254,
            7.964576244354248,   -4.207889080047607,  -3.7487030029296875,
            -2.5114004611968994, 5.777673244476318,   -4.472823619842529,
            -8.405767440795898,  -3.8579723834991455, 6.036187648773193,
            9.076417922973633,   7.101912021636963,   1.4166420698165894,
            -5.644308567047119,  -2.5986480712890625, -7.264847278594971,
            -9.782458305358887,  5.496699810028076,   -9.967339515686035,
            -6.901016712188721,  -2.8501904010772705, 3.279616355895996
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      }
    }
  }
];

if (navigator.ml) {
  identityTests.forEach((test) => {
    webnn_conformance_test(
        buildGraphAndCompute, getIdentityPrecisionTolerance, test);
  });
} else {
  test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}
